#include "gofgame/common/ui/GridLayout.h"
#include "gofgame/common/ui/Container.h"
#include "gofgame/common/IllegalArgumentException.h"

using namespace gofgame::common::ui;

GridLayout::GridLayout() {
	this->cellSize = CCSize(32, 32);
	this->cellSpacing = 0;
	this->cellPadding = 0;
}

const CCSize &GridLayout::getCellSize() const {
	return this->cellSize;
}

void GridLayout::setCellSize(const CCSize &cellSize) {
	if (this->cellSize.width != cellSize.width || this->cellSize.height != cellSize.height) {
		if (cellSize.width < 1 || cellSize.height < 1) {
			_throw(IllegalArgumentException, "ccSize must >= (1, 1)");
		}
		this->cellSize = cellSize;
		this->setDirty();
	}
}

float GridLayout::getCellSpacing() const {
	return this->cellSpacing;
}

void GridLayout::setCellSpacing(float cellSpacing) {
	if (this->cellSpacing != cellSpacing) {
		if (cellSpacing < 0) {
			_throw(IllegalArgumentException, "cellSpacing must >= 0");
		}
		this->cellSpacing = cellSpacing;
		this->setDirty();
	}
}

float GridLayout::getCellPadding() const {
	return this->cellPadding;
}

void GridLayout::setCellPadding(float cellPadding) {
	if (this->cellPadding != cellPadding) {
		if (cellPadding < 0) {
			_throw(IllegalArgumentException, "cellPadding must >= 0");
		}
		this->cellPadding = cellPadding;
		this->setDirty();
	}
}

void GridLayout::onLayout() {
	Container *container = this->getContainer();
	CCArray *children = this->getContainer()->getChildren();
	if (!children || !children->count()) {
		return;
	}
	float pl = container->getPaddingLeft();
	float pr = container->getPaddingRight();
	float pt = container->getPaddingTop();
	float tw = this->getLayoutSize().width - pl - pr;
	CCSize cellSize = this->cellSize;
	float s = this->getCellSpacing();
	float w = this->getCellSize().width;
	float p = this->getCellPadding();
	int colCount = (int)(tw + s) / (int)(w + 2 * p + s);
	if (colCount < 1) {
		colCount = 1;
	}
	float dX = cellSize.width + 2 * p + s;
	float dY = cellSize.height + 2 * p + s;
	float x = pl - s;
	float y = pt - s;
	float cX = cellSize.width - 2 * p;
	float cY = cellSize.height - 2 * p;
	int colIndex = 0;
	int childrenCount = children->count();
	int index = 0;
	while (index < childrenCount) {
		Component *component = static_cast<Component*>(children->objectAtIndex(index));
		this->layoutChild(
			component,
			x + s,
			y + s,
			cX,
			cY);
		index++;
		if (index % colCount == 0) {
			x = pl - s;
			y += dY;
		} else {
			x += dX;
		}
	}
}